#include "TestEnemy.h"

TestEnemy::TestEnemy(const Vector2df p, const Vector2df v) : BaseUnit(p,v) {
    // Load custom images (as many as you want)
    m_walking.loadFrames("images/enemy_walking.png",2,1);
    m_walking.setLooping(true);
    m_walking.setFrameRate(DECI_SECONDS);
    m_walking.setTransparentColour(MAGENTA);
    m_flipped.loadFrames("images/enemy_flipped.png",2,1);
    m_flipped.setLooping(true);
    m_flipped.setFrameRate(DECI_SECONDS);
    m_flipped.setTransparentColour(MAGENTA);
    m_pushed.loadFrames("images/enemy_pushed.png",1,1);
    m_pushed.setLooping(true);
    m_pushed.setFrameRate(DECI_SECONDS);
    m_pushed.setTransparentColour(MAGENTA);
    m_sprite = &m_walking;

    // Collision image
    //m_collision.loadImage("images/warioCollision.png");
    //m_collision.setNoCollisionColour(MAGENTA);
}

TestEnemy::~TestEnemy() {

}

//----------------------
// public declarations
//----------------------

void TestEnemy::hit(const SimpleDirection dir, BaseUnit* const player, CRstring parameter) {
    // Reaction on collision depends on state
    // Gets pushed when walking
    // Gets flipped over when pushed against a wall
    // Gets pushed more when flipped over
    // No collision detection when picked up
    if (m_state == usNORMAL) {
        m_direction = m_velocity.x / abs(m_velocity.x);
    }
    if (m_state != usNORMAL) {
        // Checks for player state
        // When player is attacking unit will get flipped over no matter what
        // and flipped around violently
        if (player->getState() == hsATTACKING)
        {
            m_state = usPICKUPABLE;
            m_sprite = &m_flipped;
            m_counter.start(max(m_counter.getTimeLeft(),2000));
            if (dir == diTOPLEFT || dir == diBOTTOMLEFT || dir == diLEFT)
            {
                m_velocity.x = 20;
                m_velocity.y = -10;
            }
            else
            {
                m_velocity.x = -20;
                m_velocity.y = -10;
            }
        }
        else
        {
            // If unit has been hit from above or below flip it into the air a bit and to the side
            if (dir == diTOPLEFT || dir == diBOTTOMLEFT)
            {
                // Pick-up implementation was done quickly and very dirty
                // I will have to redo most of it as it currently also has a lot of bug
                // For the time being just ignore it
                if (m_state == usPICKUPABLE && dir == diBOTTOMLEFT)
                {
                    ///pickUp(player);
                }
                else
                {
                    // Change state
                    m_state = usPICKUPABLE;
                    // Move to the side (= push)
                    m_velocity.x = 10;
                    m_velocity.y = -8;
                    //accelerate(Vector2df(-2,0),Vector2df(0,0));
                    m_sprite = &m_flipped;
                    // Start counter which will switch back to normal state after some time
                    m_counter.start(max(m_counter.getTimeLeft(),2000));
                }
            }
            else if (dir == diTOPRIGHT || dir == diBOTTOMRIGHT)
            {
                if (m_state == usPICKUPABLE && dir == diBOTTOMRIGHT)
                {
                    ///pickUp(player);
                }
                else
                {
                    m_state = usPICKUPABLE;
                    m_velocity.x = -10;
                    m_velocity.y = -8;
                    //accelerate(Vector2df(2,0),Vector2df(0,0));
                    m_sprite = &m_flipped;
                    m_counter.start(max(m_counter.getTimeLeft(),2000));
                }
            // If hit at the side push it away
            }
            else if (dir == diLEFT)
            {
                if (m_state == usPICKUPABLE)
                {
                    ///pickUp(player);
                }
                else
                {
                    m_state = usVULNERABLE;
                    m_sprite = &m_pushed;
                    m_velocity.x = 14;
                    accelerate(Vector2df(-2,0),Vector2df(0,0));
                    m_counter.start(max(m_counter.getTimeLeft(),500));
                }
            }
            else if (dir == diRIGHT)
            {
                if (m_state == usPICKUPABLE)
                {
                    ///pickUp(player);
                }
                else
                {
                    m_state = usVULNERABLE;
                    m_sprite = &m_pushed;
                    m_velocity.x = -14;
                    accelerate(Vector2df(2,0),Vector2df(0,0));
                    m_counter.start(max(m_counter.getTimeLeft(),500));
                }
            }
        }
    }
}

void TestEnemy::hitMap(MapData* const data, const CollisionObject* const obj) {
    Vector2df correction = obj->getTotalCorrection();
    if (m_state == usPICKUPABLE && correction.y != 0) {
        if (m_velocity.y > 8)
            m_velocity.y *= -0.3;
        else
            m_velocity.y = 0;
        if (abs(m_velocity.x) < 3)
            m_velocity.x = 0;
        else
            m_velocity.x *= 0.5;
        m_acceleration[0].y *= -1;
        m_acceleration[1].y *= -1;
    } else {
        m_velocity.y += correction.y;
    }
    if (abs(correction.x) + abs(correction.y) > 0) {
        if (m_state == usNORMAL) {
            m_state = usPICKUPABLE;
            m_counter.start(2000);
            if (correction.x != 0) {
                if (correction.x > 0) {
                    m_velocity.x = 10;
                    m_velocity.y = -6;
                    //accelerate(Vector2df(-0.5,0),Vector2df(0,0));
                } else {
                    m_velocity.x = -10;
                    m_velocity.y = -6;
                    //accelerate(Vector2df(0.5,0),Vector2df(0,0));
                }
            }
            if (correction.y != 0)
            {
                m_velocity.x = 10;
                m_velocity.y = 4;
            }
            if (m_parent) {
                m_parent->resetParent();
                m_parent = NULL;
            }
        } else {
            // If pushed against a wall, flip it over
            if (correction.x != 0) {
                if (m_state == usNORMAL) {
                    m_state = usPICKUPABLE;
                    m_sprite = &m_flipped;
                    m_counter.start(max(m_counter.getTimeLeft(),2000));
                }
                // Change movement direction
                m_velocity.x *= -1;
                m_acceleration[0].x *= -1;
                m_acceleration[1].x *= -1;
            } else {
                if (m_state == usNORMAL && obj->isOnPlatformEdge(getPosition(true),getSpeed()))
                {
                    // Change movement direction
                    m_velocity.x *= -1;
                    m_acceleration[0].x *= -1;
                    m_acceleration[1].x *= -1;
                }
            }
        }
    }
}

void TestEnemy::resetParent() {
    if (m_parent) {
        Vector2df direction = Vector2df(m_parent->getDirection(),0.0);
        m_velocity.x = m_parent->getSpeed().x + 16*direction.x;
        m_velocity.y = m_parent->getSpeed().y + 6*direction.y;
    }
    if (m_state == usNORMAL) {
        m_state = usNORMAL;
        m_counter.start(2000);
    }
    BaseUnit::resetParent();
};

//----------------------
// private declarations
//----------------------

void TestEnemy::customUpdate() {
    // Change back to normal state and reverse movement
    if (m_state == usNORMAL || m_state == usNORMAL) {
        m_state = usNORMAL;
        m_direction *= -1;
        m_velocity = Vector2df(m_maxSpeed.x * m_direction, m_maxSpeed.y);
        m_sprite = &m_walking;
    }
}
